<!--
 * @Description: 数泽MES
 * @Author: 数泽
 * @Date: 2023-10-27 16:08:02
-->
<template>
  <flexbox class="wk-user-select" align="stretch">
    <div v-loading="loading" class="wk-user-select__left">
      <div class="wk-user-select__header">
        <el-autocomplete v-model="searchInput" :fetch-suggestions="searchListUser"
                         placeholder="请输入内容" @select="searchSelect">
          <template v-slot:default="{ item }">
            <span>{{ item[config.label] }}</span>
            <span style="color: #999;">{{ `(${item.post || '暂无岗位'})` }}</span>
          </template>
        </el-autocomplete>
      </div>
      <div class="wk-user-select__body">
        <el-breadcrumb style="padding: 5px 0;" separator-class="el-icon-arrow-right">
          <el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="index">
            <a href="javascript:;" @click="breadcrumbBtn(item, index)">{{ item.label }}</a>
          </el-breadcrumb-item>
        </el-breadcrumb>
        <div class="wk-user-select__list">
          <flexbox v-for="(item, index) in showDataList" :key="index" class="wk-user-select__item">
            <el-checkbox v-if="(item.isDep && config.canSelectDep) || !item.isDep" v-model="item.isCheck"
                         :disabled="item.disabled"
                         @change="dataCheckboxChange($event, item)"/>
            <template v-if="item.isDep">
              <div class="dep-name text-one-line">
                {{ `${item[config.depLabel]}${item.currentNum > 0 ? `(${item.currentNum})` : ''}` }}
              </div>
              <el-button v-if="item.hasChildren == 1 || item.currentNum > 0"
                         :disabled="item.isCheck"
                         link
                         class="wk wk-icon-structure"
                         @click="lowerLevelClick(item)">下级
              </el-button>
            </template>
            <template v-else>
              <xr-avatar :name="item[config.label]" :size="24" :src="item.img" class="user-img"/>
              <div class="user-info">
                <div class="user-name text-one-line">{{ item[config.label] }}</div>
                <div class="user-post">{{ item.post || '暂无岗位' }}</div>
              </div>
            </template>
          </flexbox>
        </div>
      </div>
    </div>
    <div class="wk-user-select__right">
      <flexbox class="user-selects" wrap="wrap">
        <span v-for="(item, index) in selectDeps" :key="`dep${index}`"
              class="user-item text-one-line">{{
            `${item[config.depLabel]}${item.currentNum > 0 ? `(${item.currentNum})` : ''}`
          }}
          <i class="delete-icon el-icon-close" @click.stop="deleteDepUser('dep', index, item, selectDeps)"/>
        </span>
        <span v-for="(item, index) in selectUsers" :key="`user${index}`"
              class="user-item text-one-line">{{ item[config.label] }}
          <i class="delete-icon el-icon-close" @click.stop="deleteDepUser('user', index, item, selectUsers)"/>
        </span>
      </flexbox>
    </div>
  </flexbox>
</template>

<script setup>
import {
  hrmEmployeeQueryByDeptAPI,
  hrmEmployeeQueryInAPI
} from '/src/api/hrm/employee.js'
import {
  adminUserQueryByDeptAPI
} from '/src/api/admin/user.js'
import {userListAPI} from '/src/api/common.js'

import PinyinMatch from 'pinyin-match'

defineOptions({
  // 用户选择 以部门的形式
  name: 'WkDepUserView',
})

const props = defineProps({
  // 取值字段
  props: {
    type: Object,
    default: () => {
      return {}
    }
  },
  depValue: {
    type: Array,
    default: () => {
      return []
    }
  },
  userValue: {
    type: Array,
    default: () => {
      return []
    }
  }
})

const emits = defineEmits(['change'])

const optionData = reactive({
  loading: false,
  searchInput: '',
  searchUserList: [],
  // 面包头
  breadcrumbList: [],
  showDataList: [],
  // 选择的部门 选择的员工
  selectUsers: [],
  selectDeps: []
})

const {
  loading, searchInput, searchUserList,
  breadcrumbList, showDataList, selectUsers, selectDeps
} = toRefs(optionData)

const config = computed(() => {
  const defaultConfig = {
    value: 'userId',
    label: 'realname',
    depValue: 'id',
    depLabel: 'name',
    canSelectDep: true,
    userOptions: null,
    radio: false, // 仅员工
    isHrm: false,
    request: null,
  }
  const config = props.props || {}

  return {
    ...defaultConfig,
    ...config
  }
})

watch(selectUsers, () => {
  selectChange()
})

watch(selectDeps, () => {
  selectChange()
})


function created() {
  optionData.selectUsers = props.userValue
  // 下面一行，看不懂。所以我注释了
  // this.depValue = this.depValue
  if (config.value.userOptions) {
    const employeeList = config.value.userOptions
    handleArrayCheckValue('user', employeeList, optionData.selectUsers)
    optionData.showDataList = employeeList
  } else {
    getDepUserList(0)
  }
}

created()

/**
 * 列效果进行搜索
 */
function searchListUser(queryString, cb) {
  if (optionData.searchUserList && optionData.searchUserList.length || config.value.userOptions) {
    const searchUserList = config.value.userOptions || optionData.searchUserList
    if (queryString) {
      cb(searchUserList.filter(item => PinyinMatch.match(item[config.value.label] || '', queryString)))
    } else {
      cb(searchUserList)
    }
  } else {
    const request = config.value.isHrm ? hrmEmployeeQueryInAPI : userListAPI
    let params = {pageType: 0}

    request(params).then(res => {
      optionData.searchUserList = res.data.data.hasOwnProperty('list') ? (res.data.data.list || []) : (res.data.data || [])
      if (queryString) {
        cb(optionData.searchUserList.filter(item => PinyinMatch.match(item[config.value.label] || '', queryString)))
      } else {
        cb(optionData.searchUserList)
      }
    }).catch(() => {
    })
  }
}

/**
 * 搜索选择
 */
function searchSelect(item) {
  const name = config.value.value
  const selectIds = optionData.selectUsers.map(item => item[name])
  const value = item[name]
  if (!selectIds.includes(value)) {
    if (config.value.radio) {
      optionData.selectUsers = [item]
    } else {
      optionData.selectUsers.push(item)
    }

    for (let index = 0; index < optionData.showDataList.length; index++) {
      const element = optionData.showDataList[index]
      if (!element.isDep && value == element[name]) {
        element.isCheck = true
        break
      }
    }
  }
}

/**
 * 获取部门员工数据
 */
function getDepUserList(deptId, depInfo) {
  optionData.loading = true
  let request = config.value.isHrm ? hrmEmployeeQueryByDeptAPI : adminUserQueryByDeptAPI
  if (config.value.request) {
    request = config.value.request
  }
  request(deptId).then(res => {
    const data = res.data || {}
    const deptList = data.deptList || []
    deptList.forEach(item => {
      item.isDep = true
    })
    handleArrayCheckValue('dep', deptList, optionData.selectDeps)

    // employeeList 人资  userList 系统管理
    const employeeList = data.employeeList || data.userList || []
    handleArrayCheckValue('user', employeeList, optionData.selectUsers)

    optionData.showDataList = deptList.concat(employeeList)
    if (deptId == 0) {
      optionData.breadcrumbList = [{label: '组织', deptList: deptList, employeeList: employeeList}]
    } else {
      optionData.breadcrumbList.push({label: depInfo.name, deptList: deptList, employeeList: employeeList})
    }
    optionData.loading = false
  }).catch(() => {
    optionData.loading = false
  })
}

/**
 * 操作数组check的值
 * type user dep
 */
function handleArrayCheckValue(type, array, selectArray) {
  const name = type == 'user' ? config.value.value : config.value.depValue
  const selectIds = selectArray.map(item => item[name])
  array.forEach(item => {
    item.isCheck = selectIds.includes(item[name])
  })
}

/**
 * 面包屑点击
 */
function breadcrumbBtn(item, index) {
  if (index + 1 <= optionData.breadcrumbList.length - 1) {
    optionData.breadcrumbList.splice(index + 1, optionData.breadcrumbList.length - 1)
  }
  const deptList = item.deptList
  handleArrayCheckValue('dep', deptList, optionData.selectDeps)
  const employeeList = item.employeeList
  handleArrayCheckValue('user', employeeList, optionData.selectUsers)
  optionData.showDataList = deptList.concat(employeeList)
}

/**
 * 数据选择
 */
function dataCheckboxChange(isCheck, data) {
  if (data.isDep) {
    if (isCheck) {
      optionData.selectDeps.push(data)
    } else {
      const index = getArrayIndexWithItem(optionData.selectDeps, data, config.value.depValue)
      if (index >= 0) {
        optionData.selectDeps.splice(index, 1)
      }
    }
  } else {
    if (isCheck) {
      if (config.value.radio) {
        optionData.selectUsers = [data]
        handleArrayCheckValue('user', optionData.showDataList, optionData.selectUsers)
      } else {
        optionData.selectUsers.push(data)
      }
    } else {
      const index = getArrayIndexWithItem(optionData.selectUsers, data, config.value.value)
      if (index >= 0) {
        optionData.selectUsers.splice(index, 1)
      }
    }
  }
}

function getArrayIndexWithItem(array, item, name) {
  for (let i = 0; i < array.length; i++) {
    const element = array[i]
    if (element[name] == item[name]) {
      return i
    }
  }
  return -1
}

/**
 * 下一级
 */
function lowerLevelClick(item) {
  optionData.showDataList = []
  getDepUserList(item.deptId, item)
}

/**
 * 部门员工删除
 */
function deleteDepUser(type, index, data, array) {
  array.splice(index, 1)
  const name = type == 'user' ? config.value.value : config.value.depValue
  const value = data[name]
  for (let index = 0; index < optionData.showDataList.length; index++) {
    const element = optionData.showDataList[index]
    if (element.isDep) {
      if (type == 'dep' && value == element[name]) {
        element.isCheck = false
        break
      }
    } else {
      if (type == 'user' && value == element[name]) {
        element.isCheck = false
        break
      }
    }
  }
}

/**
 * 选择change
 */
function selectChange() {
  emits('change', optionData.selectUsers, optionData.selectDeps)
}

</script>

<style lang="scss" scoped>
.wk-user-select {
  height: 300px;

  &__left {
    flex: 4;
    padding: 10px 15px;
    height: 100%;
  }

  &__right {
    flex: 5;
    padding: 10px;
    border-left: 1px solid $xr-border-color-base;
    height: 100%;
    position: relative;

    .user-selects {
      overflow-y: auto;
    }

    .user-item {
      padding: 5px 15px 5px 5px;
      background-color: #F3F7FF;
      border-radius: $xr-border-radius-base;
      margin: 3px;
      position: relative;
      max-width: 200px;
    }

    .delete-icon {
      color: #999;
      cursor: pointer;
      position: absolute;
      top: 8px;
      right: 2px;

      &:hover {
        color: $xr-color-primary;
      }
    }
  }

  &__header {
    margin-bottom: 10px;

    .el-autocomplete {
      width: 100%;
    }
  }

  &__body {
    height: calc(100% - 50px);
  }

  &__list {
    height: calc(100% - 24px);
    overflow-y: auto;
  }

  &__item {
    height: 40px;

    .el-checkbox {
      margin-right: 8px;
    }

    .el-button--text {
      position: relative;
      color: #ccc;
      padding-left: 12px;
      padding-right: 12px;
      flex-shrink: 0;

      :deep( i ) {
        font-size: 13px;
        margin-right: 3px;
      }

      &:before {
        content: ' ';
        position: absolute;
        top: 8px;
        left: 0;
        bottom: 8px;
        width: 1px;
        background-color: $xr-border-color-base;
      }

      &:hover {
        color: $xr-color-primary;
      }

      &.is-disabled {
        color: #C0C4CC;
      }
    }

    .user {
      &-img {
        flex-shrink: 0;
      }

      &-info {
        flex: 1;
        padding: 0 8px;
      }

      &-name {
        max-width: 200px;
      }

      &-post {
        color: #999;
        margin-top: 2px;
        font-size: 12px;
      }
    }

    .dep {
      &-name {
        flex: 1;
        padding-right: 8px;
      }
    }
  }
}
</style>
